package net.oaktoncc.brultech_ecm1220;

import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import net.oaktoncc.Operation;
import net.oaktoncc.SerialAuditDevice;

/**
 * TODO: Javadoc
 *
 * @author aeagle
 */
public class BrultechECM1220 extends SerialAuditDevice {
    private static final byte[] ACK = new byte[]{ (byte)0xFC };

    public void downloadData(SerialPort port, final PrintWriter writer) throws IOException {
        new DownloadDataOperation(port).execute(writer);
    }

    public class DownloadDataOperation implements Operation {
        private final SerialPort port;
        public DownloadDataOperation(SerialPort port) {
            this.port = port;
        }

        public void execute() throws IOException {
            execute(new PrintWriter(System.out));
        }

        private void createDataRecord(final PrintWriter writer, int[] frame) {
            // outStream.println("frame " + Arrays.toString(frame));
            int voltage = frame[0];
            int ch1 = frame[1] + 255*frame[2];
            int ch2 = frame[3] + 255*frame[4];
            writer.println("Voltage " + voltage + " ch1 " + ch1 + " ch2 " + ch2);
        }

		public void execute(final PrintWriter writer) throws IOException {
			InputStream in = port.getInputStream();
            OutputStream out = port.getOutputStream();

            byte response;
            // Toggle real-time mode off
            out.write(ACK);
            response = (byte)in.read();
            writer.println("ACK " + response);

            out.write("TOG".getBytes());
            response = (byte)in.read();
            writer.println("TOG " + response);

            out.write("OFF".getBytes());
            response = (byte)in.read();
            writer.println("OFF " + response);

            out.write(ACK);
            response = (byte)in.read();
            writer.println("ACK " + response);

            out.write("DNL".getBytes());
            response = (byte)in.read();
            writer.println("DNL1 " + response);

            out.write("DNL".getBytes());
            response = (byte)in.read();
            writer.println("DNL2 " + response);

            int lmt = 32;
            for (int count = 0; count < lmt; count++) {
                int i = in.read();
                writer.println("unit info " + i);
            }

            out.write(ACK);
            lmt=2;
            for (int count = 0; count < lmt; count++) {
                int i = in.read();
                writer.println("storage interval " + i);
            }

            out.write(ACK);
            lmt=2;
            for (int count = 0; count < lmt; count++) {
                int i = in.read();
                writer.println("pointer " + i);
            }

            out.write(ACK);
            int lastchar = 0;
            int frameptr = 0;
            int[] frame = new int[5];
            for (int i = in.read(); i != -1; i = in.read()) {
                if (i==254 && lastchar==254) {
                    break;
                }
                frame[frameptr] = i;
                if (frameptr == 4) {
                    createDataRecord(writer, frame);
                    frameptr = 0;
                } else frameptr++;

                lastchar = i;
            }

            out.write(ACK);
            response = (byte)in.read();
            writer.println("checksum " + response);

            out.write(ACK);
            out.write("END".getBytes());

		}
    }
}
